<?php

use Lib\Base\Common;
use Lib\Base\L5;
use Lib\Base\Request;
use Lib\Base\Response;
use Lib\Service\TGLog;

if (!function_exists('recordLog')) {

    /**
     * 记录日志信息
     * @param string $content 日志内容
     * @param string $file 文件
     * @param string $line 行号
     * @param int $level 日志级别，线上环境可以直接使用常量。调试信息：LP_DEBUG（黑色）, 普通日志：LP_INFO （蓝色）, 错误日志：LP_ERROR（红色） 表示日志级别
     */
    function recordLog($content, $file = __FILE__, $line = __LINE__, $level = LP_DEBUG)
    {
        //自动获取调用方的文件和行数
        if (basename($file) == 'Functions.php') {
            $debugInfo = debug_backtrace();
            $file = $debugInfo[0]['file'];
            $line = $debugInfo[0]['line'];
        }

        //ULink本地测试或者cli模式运行将日志写入本地
        if (defined('ENV') && ENV == 'test' || (php_sapi_name() == 'cli' && !isSwoole())) {
            //      if (RUN_ENV == 'internal') {
            $logPath = APP_PATH . DIRECTORY_SEPARATOR . 'log';
            if (!is_dir($logPath)) {
                mkdir($logPath, 0777, true);
            }

            //$content = "文件：" . $file . ", 行数：" . $line. " , " . $content;
            file_put_contents($logPath . DIRECTORY_SEPARATOR . date('Ymd') . '.log', date('Y-m-d H:i:s') . ' --- ' . $content . PHP_EOL, FILE_APPEND);
        } else {
            $openid = '';
            $activityId = '';
            $amsSerial = '';
            $module = 'Condition';

            if (RUN_ENV == 'ulink') {
                global $ULINK_INSTANCEID;
                $module = 'ULink';
                $openid = Request::param('openid');
                if (empty($openid)) {
                    $openid = Request::param('iUin');
                }
                $activityId = empty($ULINK_INSTANCEID) ? LIB_DEFAULT_INSTANCEID : $ULINK_INSTANCEID;
            } else if (RUN_ENV == 'internal') {
                $openid = Request::param('iUin');
                $activityId = Request::param('iAmsActivityId');
                if (!$activityId) {
                    $activityId = defined('PAAS_INSTANCE_ID') ? PAAS_INSTANCE_ID : 281592;
                }
            }

            //道聚城回调接口，账号是通过sBuyUid参数传递
            if (empty($openid)) {
                $openid = Request::param('sBuyUid');
            }

            $content = Common::charsetConvert($content, 'UTF-8', 'GBK');
            $amsSerial = Request::getParam('sAmsSerial');

            //判断环境获取log类
            if (isSwoole()) {
                $obj = Request::serverParam('logObj');
            } else {
                global $NTX_LOGGER;
                $obj = $NTX_LOGGER;
            }
            $obj->writePlatLog($file, $line, $level, $activityId, "AMS", "[{$amsSerial}][{$module}][OPENID:{$openid}]" . $content . "\n");
        }
    }
}

if (!function_exists('recordKLog')) {

    /**
     * klog日志记录
     *
     * @param $logInfo string 需要记录的日志
     * @return null
     */
    function recordKLog($code, $scode, $server, $log)
    {
        //测试
        if (ENV == 'test') {
            $logPath = APP_PATH . DIRECTORY_SEPARATOR . 'logs';
            file_put_contents($logPath . DIRECTORY_SEPARATOR . date('Ymd') . '.log', date('Y-m-d H:i:s') . ' ---- ' . 'code=' . $code . '&scode=' . $scode . '&server=' . $server . '&log=' . $log . PHP_EOL, FILE_APPEND);
        } else {
            $obj = new \Logger(Request::getRequest());
            $obj->sys_send_log($code, $scode, $server, $log);
        }
    }
}

if (!function_exists('tnm2Report')) {
    /**
     * tnm2特性上报
     * @param int $attrId 特性ID
     * @param int $incrNum [可选，默认1] 每次请求上报数量
     *
     */
    function tnm2Report($attrId, $incrNum = 1)
    {
        if (defined('ENV') && ENV != 'test' && function_exists('Attr_API') && !empty($attrId)) {
            Attr_API($attrId, $incrNum);
        }
    }
}

if (!function_exists('createAmsSerial')) {
    /**
     * 生成AmsSerial流水
     *
     * @param int $iAmsActivityId 活动号
     * @param string $sServiceType 业务代码
     * @return string
     */
    function createAmsSerial($iAmsActivityId = 155589, $sServiceType = 'ULINK')
    {
        $openid = Request::param('openid');
        $iTmpUin = Common::time33($openid);
        $iFlowId = Common::getRandStr(5, 1, 1);

        $strRand = getAmsRandStr($iAmsActivityId, $iFlowId, $iTmpUin);
        return 'AMS-' . strtoupper($sServiceType) . '-' . date('mdHis') . '-' . $strRand . '-' . $iAmsActivityId . '-' . $iFlowId;
    }
}

if (function_exists('awpOutputJson')) {
    /**
     * awp系统cgi统一输出函数
     * @param int $suc 0-成功，其他-异常
     * @param int $ret -1
     * @param string $msg 输出信息
     */
    function awpOutputJson(int $suc, int $ret = -1, string $msg)
    {
        $vResult = array('isSuc' => $suc, 'iRet' => $ret, 'sInfo' => htmlspecialchars($msg));
        echo json_encode($vResult);
        exit;
    }
}

if (!function_exists('outputJson')) {

    /**
     * outputJson
     *
     * @param $iRet
     * @param $sMsg
     * @param array $jData
     * @param bool $filterHtmlTag true-html标签转实体 ，false-html标签不转实体，前端一定要防止xss
     * @return bool
     *
     */
    function outputJson($iRet, $sMsg, $jData = [], $filterHtmlTag = true)
    {
        //开始时间
        if (isSwoole()) {
            $cgiStartTime = Request::getParam('cgiStartTime');
        } else {
            global $cgiStartTime;
        }

        //结束时间
        $cgiEndTime = microtime(true);

        $redata = [
            'iRet' => $iRet,
            'sMsg' => $sMsg,
            'jData' => $jData,
            'execTime' => round((($cgiEndTime - $cgiStartTime) * 1000), 3)
        ];

        if (RUN_ENV == "internal") {
            $redata['sSerial'] = Request::getParam("sAmsSerial");
        }

        if (RUN_ENV == 'ulink') {
            $redata['sULinkSerial'] = Request::getParam("sAmsSerial");
            if (ENV != 'test') {
                // 1/1000 概率上报数据给活动回放接口
                $randNum = mt_rand(1, 1000000);
                if ($randNum <= 100000) {
                    if (Request::serverParam('REQUEST_METHOD') && in_array(Request::serverParam('REQUEST_METHOD'), ['GET', 'POST'])) {
                        $recordInfo = [
                            'SCRIPT_NAME' => Request::serverParam('HTTP_HOST') . Request::serverParam('SCRIPT_NAME'),
                            'REQUEST_METHOD' => Request::serverParam('REQUEST_METHOD'),
                            'GET' => Request::getParam(),
                            'POST' => Request::postParam(),
                            'RESPONSE' => $redata,
                            'HTTP_REFERER' => Request::serverParam('HTTP_REFERER'),
                            'HTTP_USER_AGENT' => Request::serverParam('HTTP_USER_AGENT'),
                        ];
                        $host = L5::getHostInfo('64069121', '262930432');
                        if ($host !== false) {
                            $udp = new \UdpDgram();
                            $conRet = $udp->connect($host['hostIp'], $host['hostPort']);
                            if ($conRet == 0) {
                                $udp->send(serialize($recordInfo));
                            }
                        }
                    }
                }

                $tglog = new TGLog(TGLOG_SERVER_INFO);

                $costTime = ($cgiEndTime * 1000) - ($cgiStartTime * 1000);
                $apiName = Request::param('route') ? Request::param('route') : (Request::param('c') . '/' . Request::param('a'));

                //所有请求都上报tglog-UlinkRequest表
                $reqData = [
                    ULINK_SAPPID,
                    Request::param('game'),
                    Request::param('iActId'),
                    '',
                    Request::param('openid'),
                    Common::getClientIp(),
                    date('Y-m-d H:i:s'),
                    '',
                    '',
                    '',
                    $apiName,
                    '2',
                    intval($costTime),
                    $redata['iRet'] == '0' ? Request::getParam('sAmsSerial') : ''
                ];

                $tglog->setTbName('UlinkRequest');
                $tglog->sendLog($reqData);

                //业务异常上报tglog-UlinkError表
                if ($redata['iRet'] != 0) {
                    $trace = getTrace();
                    $reqErrData = [
                        ULINK_SAPPID,
                        Request::param('game'),
                        Request::param('iActId'),
                        $apiName,
                        '',
                        Request::param('openid'),
                        '1', //错误等级
                        $redata['iRet'],
                        $trace['line'],
                        $redata['sMsg'],
                        Request::serverParam('SERVER_ADDR'),
                        Request::getParam('sAmsSerial'),
                        date('Y-m-d H:i:s'),
                        '',
                        '',
                        '',
                        $apiName,
                        '2',
                        intval($costTime)
                    ];
                    $tglog->setTbName('UlinkError');
                    $tglog->sendLog($reqErrData);
                }
            }
        }
        if ($filterHtmlTag !== false) {
            $redata = Common::filterHtml($redata);
        }
        return Response::outputJson($redata);
    }
}

if (!function_exists('outputJsonp')) {
    function outputJsonp($data, $varName = '')
    {
        $redata = Common::filterHtml($data);
        if ($varName === '') {
            Response::outputJsonp($redata);
        } else {
            if (!preg_match('/^[_a-zA-Z][\da-zA-Z_]+$/', $varName)) {
                $varName = 'retData';
            }
            $redata = 'var ' . $varName . '=' . json_encode($redata) . ';';
            Response::outputJson($redata);
        }
    }
}

if (!function_exists('outputHeader')) {
    function outputHeader($data, $header)
    {
        Response::outputHeader($data, $header);
    }
}

if (!function_exists('getAmsRandStr')) {
    /**
     * @brief 随机请求码
     */
    function getAmsRandStr($iActivityId, $iFlowId, $iUin)
    {
        $iRandomNum = mt_rand(1, 99999999);
        $sUip = Common::getClientIp();
        $iUserIpNum = bindec(decbin(ip2long($sUip)));
        list($usec, $sec) = explode(' ', microtime());
        $fSeed = (float) $sec + ((float) $usec * 1000000) + (float) $iUin + (float) $iActivityId + (float) $iFlowId + (float) $iUserIpNum + (float) $iRandomNum;
        mt_srand((int) $fSeed);
        $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz';
        $sAmeReqCode = $str[mt_rand(0, 61)] . $str[mt_rand(0, 61)] . $str[mt_rand(0, 61)] . $str[mt_rand(0, 61)] . $str[mt_rand(0, 61)] . $str[mt_rand(0, 61)];
        return $sAmeReqCode;
    }
}

if (!function_exists('getTrace')) {
    function getTrace($level = 1)
    {
        $trace = debug_backtrace();
        for ($i = 0; $i < $level; $i++) {
            array_shift($trace);
        }
        $t = array_shift($trace);
        $file = isset($t['file']) ? $t['file'] : '{main}';
        $line = $t['line'];
        $t = array_shift($trace);
        $class = isset($t['class']) ? $t['class'] . $t['type'] . $t['function'] : $t['function'];
        $trace = array('file' => $file . '[' . $class . ']', 'line' => $line);
        return $trace;
    }
}

/**
 * OSS_LOG
 *
 * @param $codefilename
 * @param $codefileline
 * @param $loglevel
 * @param $sLog
 */
function OSS_LOG($codefilename, $codefileline, $loglevel, $sLog)
{
    global $g_log_level, $g_debug_log, $g_is_test_mechine;

    //error_log(date('Y-m-d H:i:s').'--'.'['.$codefilename.']['.$codefileline.']['.$loglevel.']not_log'.$g_log_level."\n",3,AMS_SERVER_LOG."_".date("YmdH").".txt");
    if (!$g_is_test_mechine) {
        if (!$g_debug_log) {
            return;
        }
    }

    if ($loglevel < $g_log_level) {
        //error_log(date('Y-m-d H:i:s').'--'.'['.$codefilename.']['.$codefileline.']['.$loglevel.']not log ',3,AMS_SERVER_LOG."_".date("YmdH").".txt");

        return;
    }

    $sLog = $sLog . " \n";
    error_log(date('Y-m-d H:i:s') . '--' . '[' . $codefilename . '][' . $codefileline . '][' . $loglevel . ']' . $sLog, 3, AMS_SERVER_LOG . "_" . date("YmdH") . ".txt");
}

function OSS_LOG_ERR($codefilename, $codefileline, $loglevel, $sLog)
{
    $sLog = $sLog . " \n";
    error_log(date('Y-m-d H:i:s') . '--' . '[' . $codefilename . '][' . $codefileline . '][' . $loglevel . ']' . $sLog, 3, AMS_SERVER_LOG . "_ER_" . date("YmdH") . ".txt");
}

/**
 * 删除数组中指定值
 *
 * @param $arr
 * @param $value
 * @return mixed
 */
function delByValue($arr, $value)
{
    if (!is_array($arr)) {
        return $arr;
    }
    foreach ($arr as $k => $v) {
        if ($v == $value) {
            unset($arr[$k]);
        }
    }
    return $arr;
}


/**
 * 分割数组
 *
 * @param array $arrF 数组
 * @param int $user_count 分成几组
 * @param int $group_num 每组多少个
 * @return array
 */
function arrayGroup($arrF, $user_count, $group_num)
{
    $arrT = [];
    for ($i = 0; $i < $user_count; $i++) {
        if ($i == $user_count - 1) {
            $arrT[] = array_slice($arrF, $i * $group_num);
        } else {
            $arrT[] = array_slice($arrF, $i * $group_num, $group_num);
        }
    }
    return $arrT;
}

/**
 * 是否是swoole环境
 *
 * @return bool
 */
function isSwoole()
{
    if (defined('OSS_NOT_SWOOLE') && constant("OSS_NOT_SWOOLE") == true) {
        return false;
    } else {
        return true;
    }
}
